//
// Created by yuping.li on 10/17/24.
//

#include "context.h"
#include <stdarg.h>

void trampoline(void) {
  while (1);
}

void make_context(lcontext_t* context, void* func, int32_t argc, ...) {
  uintptr_t* sp;
  uintptr_t* regp;
  va_list va;
  int32_t i;

  sp = (uintptr_t*)((uintptr_t)(context->stack.ss_sp) + context->stack.ss_size);
  sp = (uintptr_t*)(((uintptr_t) sp & -16L) - 8);

  if (argc > 4) {
    sp -= (argc - 4);
  }

  context->reg.sp = (uintptr_t) sp;
  context->reg.pc = (uintptr_t) func;
  context->reg.lr = (uintptr_t) &trampoline;

  va_start(va, argc);

  regp = &(context->reg.r0);

  for (i = 0; (i < argc && i < 4); i++) {
    *regp++ = va_arg (va, uintptr_t);
  }

  for (; i < argc; i++) {
    *sp++ = va_arg (va, uintptr_t);
  }

  va_end(va);

}
